package com.jiashn.minio.utils;

import com.jiashn.minio.mapper.OpuSysFilesMapper;
import com.jiashn.minio.service.OpuSysFilesService;
import io.minio.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;

/**
 * @author: jiangjs
 * @description: minio工具类
 * @date: 2023/10/20 10:50
 **/
@Component
@Slf4j
public class MinioHelper {

    @Resource
    private MinioClient minioClient;

    /**
     * 校验当前bucket是否存在，不存在则创建
     * @param bucketName 桶
     */
    private void existBucket(String bucketName){
        try {
            boolean isExist = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
            if (!isExist){
                minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    /**
     * 单个文件上传
     * @param file 文件
     * @param bucketName 桶名称
     * @return 执行结果
     */
    public Boolean upLoadSingleFile(MultipartFile file,String bucketName,String fileName){
        try(InputStream ism = file.getInputStream()){
            return upLoadInputStream(ism,bucketName,fileName);
        }catch (Exception e){
            log.error("单个文件上传报错："+e.getMessage());
            e.printStackTrace();
            return Boolean.FALSE;
        }
    }

    /**
     * 文件流上传
     * @param ism 文件流
     * @param bucketName 桶名称
     * @param fileName 文件名称
     * @return 执行结果
     */
    public Boolean upLoadInputStream(InputStream ism,String bucketName,String fileName){
        try {
            existBucket(bucketName);
            minioClient.putObject(PutObjectArgs.builder()
                    .bucket(bucketName)
                    .object(fileName)
                    .stream(ism,ism.available(),-1)
                    .build());
            return Boolean.TRUE;
        }catch (Exception e){
            log.error("文件流上传报错："+e.getMessage());
            e.printStackTrace();
            return Boolean.FALSE;
        }
    }

    /**
     * 多文件上传
     * @param files 多文件
     * @param bucketName 桶名称
     * @return 返回结果
     */
    public List<Map<String,Object>> upLoadMoreFile(MultipartFile[] files, String bucketName){
        existBucket(bucketName);
        InputStream ism = null;
        List<Map<String,Object>> res = new ArrayList<>(files.length);
        try {
            for (MultipartFile file : files) {
                ism = file.getInputStream();
                String filename = file.getOriginalFilename();
                minioClient.putObject(PutObjectArgs.builder()
                        .bucket(bucketName)
                        .object(filename)
                        .stream(ism,ism.available(),-1)
                        .contentType(file.getContentType())
                        .build());
                Map<String,Object> resMap = new HashMap<>(2);
                resMap.put("fileName",filename);
                resMap.put("result",Boolean.TRUE);
                res.add(resMap);
            }
        }catch (Exception e){
            log.error("文件流上传报错："+e.getMessage());
            e.printStackTrace();
        }finally {
            if (Objects.nonNull(ism)){
                try {
                    ism.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return res;
    }


    /**
     * 下载文件
     * @param fileName 文件名称
     * @param bucketName 桶名称
     * @return 文件流
     */
    public InputStream downLoadFile(String fileName,String bucketName){
        InputStream ism = null;
        try {
            ism = minioClient.getObject(GetObjectArgs.builder()
                            .bucket(bucketName)
                            .object(fileName).build());
        } catch (Exception e) {
            log.error(String.format("下载文件（%s）报错：%s",fileName,e.getMessage()));
            e.printStackTrace();
        }
        return ism;
    }

    /**
     * 删除文件信息
     * @param bucketName 桶名称
     * @param fileName 文件名称
     * @return 删除结果
     */
    public Boolean removeFile(String bucketName,String fileName){
        try {
            minioClient.removeObject(RemoveObjectArgs.builder()
                    .bucket(bucketName)
                    .object(fileName).build());
            return Boolean.TRUE;
        } catch (Exception e) {
            log.error(String.format("删除文件（%s）报错：%s",fileName,e.getMessage()));
            e.printStackTrace();
            return Boolean.FALSE;
        }
    }


}
